package cn.net.wanji.service.iml;


import cn.net.wanji.entity.*;
import cn.net.wanji.mapper.MonitorMapper;
import cn.net.wanji.service.MonitorService;
import cn.net.wanji.utils.StringUtils;
import cn.net.wanji.utils.TimeUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.vertx.core.json.Json;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

import static cn.net.wanji.config.CommonParamConfig.ALL_CAR_TYPE;
import static cn.net.wanji.config.CommonParamConfig.ALL_EVENT_TYPE;
import static cn.net.wanji.job.RefreshGantryDataJob.gantryFlagInfoMap;
import static cn.net.wanji.utils.StringUtils.isFirstCharOne;
import static cn.net.wanji.utils.TimeUtils.calculateMinutesDifference;
import static cn.net.wanji.utils.TimeUtils.isTimeDifferenceGreaterThanOneHour;

/**
 * @author weining
 */
@Slf4j
@Service
public class MonitorServiceImpl implements MonitorService {

    @Resource
    MonitorMapper monitorMapper;

    @Value("${event.time}")
    private String time;

    public static HashMap<String, String> eventHashMap = new HashMap<>();

    @Override
    public JSONObject monitorData(String date) {
        // long startTimeMillis = System.currentTimeMillis();
        // 获取当前日期
        String upGantryId = gantryFlagInfoMap.get("1");
        MonitorData monitorData = new MonitorData();
        CarNum carNum = monitorMapper.selectCarNumber(date, upGantryId);
        // long getCarNumTime = System.currentTimeMillis();
        // log.info("获取客车货车数量耗时：{}", getCarNumTime - startTimeMillis);
        // 获取当天所有时间段
        List<HourNum> hourNums = monitorMapper.getTrafficTrends(date);
        // long getHourNumTime = System.currentTimeMillis();
        // log.info("获取当天所有时间段数量耗时：{}", getHourNumTime - getCarNumTime);
        HashMap<Integer, Integer> hourMap = new HashMap<>();
        for (HourNum hourNum : hourNums) {
            String hourStr = hourNum.getHour();
            LocalDateTime dateTime = LocalDateTime.parse(hourStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            int hour = dateTime.getHour();
            hourMap.put(hour + 1, hourNum.getNumber());
        }
        List<HourNum> hourNumList = new ArrayList<>();
        // 获取当前时间
        LocalDateTime nowDate = LocalDateTime.now();
        // 获取当前小时数
        int currentHour = nowDate.getHour() + 1;
        for (int i = 0; i <= currentHour; i++) {
            if (hourMap.containsKey(i)) {
                HourNum hourNum = new HourNum();
                hourNum.setHour(String.valueOf(i));
                hourNum.setNumber(hourMap.get(i));
                hourNumList.add(hourNum);
            } else {
                HourNum hourNum = new HourNum();
                hourNum.setHour(String.valueOf(i));
                hourNum.setNumber(0);
                hourNumList.add(hourNum);
            }
        }
        // long getHourNumOptTime = System.currentTimeMillis();
        // log.info("获取当天所有时间段数量处理耗时：{}", getHourNumOptTime - getHourNumTime);

        // 查询所有的特殊车辆
        List<SpecialCar> specialCars = monitorMapper.selectSpecialByDate(date);
        // long getSpecialCarsOptTime = System.currentTimeMillis();
        // log.info("获取当天所有的特殊车辆段数量耗时：{}", getSpecialCarsOptTime - getHourNumOptTime);
        int count = 0;
        ArrayList<SpecialCar> specialList = new ArrayList<>();
        for (SpecialCar specialCar : specialCars) {
            if (specialCar.getEventType().contains("危化")) {
                specialCar.setType("17");
                count = count + 1;
            }
            specialList.add(specialCar);
        }
        // long getOptSpecialCarsOptTime = System.currentTimeMillis();
        // log.info("获取当天所有的特殊车辆段数量处理耗时：{}", getOptSpecialCarsOptTime - getSpecialCarsOptTime);
        // 查询所有的事件列表
        List<EventCar> eventCars = monitorMapper.selectEventByDate(date, String.valueOf(Integer.parseInt(time) * 60));
        // long getEventCarsTime = System.currentTimeMillis();
        // log.info("获取当天所有的事件列表数量耗时：{}", getEventCarsTime - getOptSpecialCarsOptTime);
        List<EventCar> eventCarArrayList = new ArrayList<>();
        int overNum = 0;
        int slowNum = 0;
        int retentionNum = 0;
        // 对事件车辆进行处理
        for (EventCar eventCar : Collections.unmodifiableList(eventCars)) {
            if ("1".equals(eventCar.getEventType())) {
                slowNum++;
            } else if ("2".equals(eventCar.getEventType())) {
                overNum++;
            } else if ("3".equals(eventCar.getEventType())) {
                retentionNum++;
                // 根据上下桥时间 获取滞留时间
                String downBridgeTime = eventCar.getDownBridgeTime();
                String upBridgeTime = eventCar.getUpBridgeTime();
                if (StringUtils.isEmpty(downBridgeTime)) {
                    LocalDateTime now = LocalDateTime.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    String nowTime = now.format(formatter);
                    eventCar.setStopTime(calculateMinutesDifference(upBridgeTime, nowTime));
                } else {
                    eventCar.setStopTime(calculateMinutesDifference(upBridgeTime, downBridgeTime));
                }
            }
            eventCarArrayList.add(eventCar);
        }
        eventCarArrayList.sort(Comparator.comparing(EventCar::getGantryTime).reversed());
        HashMap<String, String> hashMap = new HashMap<>();
        for (EventCar eventCar : eventCarArrayList) {
            hashMap.put(eventCar.getCarId(), eventCar.getEventType());
        }
        eventHashMap = hashMap;
        monitorData.setEventArray(eventCarArrayList);
        // long getEventCarsOptTime = System.currentTimeMillis();
        // log.info("获取当天所有的事件列表数量处理耗时：{}", getEventCarsOptTime - getEventCarsTime);
        monitorData.setCarNum(carNum.getCarNumber());
        monitorData.setTruckNum(carNum.getTruckNumber());
        monitorData.setSpecialArray(specialList);
        monitorData.setEventNum(eventCars.size());
        monitorData.setOverSpeedNum(overNum);
        monitorData.setLowSpeedNum(slowNum);
        monitorData.setRetentionNum(retentionNum);
        monitorData.setDangerNum(count);
        monitorData.setHourArray(hourNumList);
        return monitorData.toJson();
    }

    @Override
    public List<EventCar> events(EventParam eventParam) {
        eventParam.setStopTime(Integer.parseInt(time) * 60);
        // 获取所有的事件
        List<EventCar> resultList = monitorMapper.selectEventByEventParam(eventParam);
        return resultList;
    }

    @Override
    public List<CrossCar> getCrossingData(CrossingDataParam crossingDataParam) {
        // 获取所有的过桥数据
        List<CrossCar> resultList = monitorMapper.selectCrossDataByEventParam(crossingDataParam);
        return resultList;
    }

    @Override
    public JSONObject getCrossingDataAnalysis(CrossingDataParam crossingDataParam) {
        // 将字符串转换为 LocalDateTime 对象
        String startTime = crossingDataParam.getStartTime();
        String endTime = crossingDataParam.getEndTime();
        LocalDateTime dateTime1 = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime dateTime2 = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<TimeTypeNum> timeTypeNums;
        List<TimeTypeNum> eventTypeNums;
        crossingDataParam.setTime(String.valueOf(Integer.parseInt(time) * 60));
        List<String> dateRange;
        // 判断两个日期时间是否相差一天
        boolean flag = Math.abs(ChronoUnit.DAYS.between(dateTime1, dateTime2)) > 1;
        if (flag) {
            //按天获取所有的天
            dateRange = TimeUtils.getDateRange(startTime, endTime);
            // 获取车辆集合列表
            timeTypeNums = monitorMapper.selectCrossDataTypeByDay(crossingDataParam);
            eventTypeNums = monitorMapper.selectEventDataTypeByDay(crossingDataParam);
        } else {
            dateRange = TimeUtils.getAllHoursBetween(startTime, endTime);
            timeTypeNums = monitorMapper.selectCrossDataTypeByHour(crossingDataParam);
            eventTypeNums = monitorMapper.selectEventDataTypeByHour(crossingDataParam);
        }
        JSONArray carFlowArray = new JSONArray();
        JSONArray carTypeArray = new JSONArray();
        JSONArray eventFlowArray = new JSONArray();
        JSONArray eventTypeArray = new JSONArray();
        HashMap<String, JSONArray> dataHashMap = new HashMap<>();
        // 获取所有的车辆类型集合
        for (TimeTypeNum timeTypeNum : timeTypeNums) {
            LocalDateTime dateTime = LocalDateTime.parse(timeTypeNum.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            // 转换为年月日格式的字符串
            String dayTime;
            if (flag) {
                dayTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            } else {
                dayTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
            }
            if (dataHashMap.containsKey(dayTime)) {
                JSONArray jsonArray = dataHashMap.get(dayTime);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", timeTypeNum.getType());
                jsonObject.put("number", timeTypeNum.getNumber());
                jsonArray.add(jsonObject);
                dataHashMap.put(dayTime, jsonArray);
            } else {
                JSONArray jsonArray = new JSONArray();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", timeTypeNum.getType());
                jsonObject.put("number", timeTypeNum.getNumber());
                jsonArray.add(jsonObject);
                dataHashMap.put(dayTime, jsonArray);
            }
        }
        for (String s : dateRange) {
            if (dataHashMap.containsKey(s)) {
                JSONArray jsonTypeArray = new JSONArray();
                //计算车辆数量
                JSONObject jsonFlowObject = new JSONObject();
                jsonFlowObject.put("time", s);
                Integer total = 0;
                for (Integer type : ALL_CAR_TYPE) {
                    JSONArray jsonType = dataHashMap.get(s);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type", type);
                    jsonObject.put("number", 0);
                    for (Object o : jsonType) {
                        JSONObject obj = JSON.parseObject(String.valueOf(o));
                        if (Objects.equals(obj.getInteger("type"), type)) {
                            jsonObject.put("number", obj.getInteger("number"));
                            total = total + obj.getInteger("number");
                        }
                    }
                    jsonTypeArray.add(jsonObject);
                }
                jsonFlowObject.put("number", total);
                carFlowArray.add(jsonFlowObject);
                JSONObject jsonType = new JSONObject();
                jsonType.put("time", s);
                jsonType.put("typeInfo", jsonTypeArray);
                carTypeArray.add(jsonType);
            } else {
                JSONObject jsonType = new JSONObject();
                JSONArray jsonTypeArray = new JSONArray();
                for (Integer type : ALL_CAR_TYPE) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type", type);
                    jsonObject.put("number", 0);
                    jsonTypeArray.add(jsonObject);
                }
                jsonType.put("time", s);
                jsonType.put("typeInfo", jsonTypeArray);
                carTypeArray.add(jsonType);
                //计算车辆数量
                JSONObject jsonFlowObject = new JSONObject();
                jsonFlowObject.put("time", s);
                jsonFlowObject.put("number", 0);
                carFlowArray.add(jsonFlowObject);
            }
        }
        // 获取所有的事件类型集合
        HashMap<String, JSONArray> eventHashMap = new HashMap<>();
        for (TimeTypeNum eventTypeNum : eventTypeNums) {
            LocalDateTime dateTime = LocalDateTime.parse(eventTypeNum.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            // 转换为年月日格式的字符串
            String dayTime;
            if (flag) {
                dayTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            } else {
                dayTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
            }
            if (eventHashMap.containsKey(dayTime)) {
                JSONArray jsonArray = eventHashMap.get(dayTime);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", eventTypeNum.getType());
                jsonObject.put("number", eventTypeNum.getNumber());
                jsonArray.add(jsonObject);
                eventHashMap.put(dayTime, jsonArray);
            } else {
                JSONArray jsonArray = new JSONArray();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", eventTypeNum.getType());
                jsonObject.put("number", eventTypeNum.getNumber());
                jsonArray.add(jsonObject);
                eventHashMap.put(dayTime, jsonArray);
            }
        }
        for (int i = 0, dateRangeSize = dateRange.size(); i < dateRangeSize; i++) {
            String s = dateRange.get(i);
            if (eventHashMap.containsKey(s)) {
                JSONArray jsonTypeArray = new JSONArray();
                //计算车辆数量
                JSONObject jsonFlowObject = new JSONObject();
                jsonFlowObject.put("time", s);
                int total = 0;
                for (Integer type : ALL_EVENT_TYPE) {
                    JSONArray jsonType = eventHashMap.get(s);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type", type);
                    jsonObject.put("number", 0);
                    for (Object o : jsonType) {
                        JSONObject obj = JSON.parseObject(String.valueOf(o));
                        if (Objects.equals(obj.getInteger("type"), type)) {
                            jsonObject.put("number", obj.getInteger("number"));
                            total = total + obj.getInteger("number");
                        }
                    }
                    jsonTypeArray.add(jsonObject);
                }
                jsonFlowObject.put("number", total);
                eventFlowArray.add(jsonFlowObject);
                JSONObject jsonType = new JSONObject();
                jsonType.put("time", s);
                jsonType.put("typeInfo", jsonTypeArray);
                eventTypeArray.add(jsonType);
            } else {
                JSONArray jsonTypeArray = new JSONArray();
                for (Integer type : ALL_EVENT_TYPE) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type", type);
                    jsonObject.put("number", 0);
                    jsonTypeArray.add(jsonObject);
                }
                //计算车辆数量
                JSONObject jsonFlowObject = new JSONObject();
                jsonFlowObject.put("time", s);
                jsonFlowObject.put("number", 0);
                eventFlowArray.add(jsonFlowObject);
            }
        }
        // 获取所有的车型总数
        List<TimeTypeNum> carTypeNum = monitorMapper.selectCarTypeNumber(crossingDataParam);
        List<TimeTypeNum> eventTypeNum = monitorMapper.selectEventTypeNumber(crossingDataParam);
        //获取所有的事件数
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("carTypeNum", carTypeNum);
        jsonObject.put("eventTypeNum", eventTypeNum);
        jsonObject.put("carTypeArray", carTypeArray);
        jsonObject.put("carFlowArray", carFlowArray);
        jsonObject.put("eventTypeArray", eventTypeArray);
        jsonObject.put("eventFlowArray", eventFlowArray);
        return jsonObject;
    }

    @Override
    public List<AntennaInfo> getAntennaInfo() {
        ArrayList<AntennaInfo> antennaInfos = new ArrayList<>();
        for (AntennaInfo antennaInfo : monitorMapper.selectAntennaInfo()) {
            AntennaInfo antenna = new AntennaInfo();
            antenna.setAId(antennaInfo.getAId());
            if (antennaInfo.getUpdateTime() != null) {
                if (isTimeDifferenceGreaterThanOneHour(antennaInfo.getUpdateTime())) {
                    antenna.setStatus("0");
                } else {
                    String status = antennaInfo.getStatus();
                    antenna.setStatus(String.valueOf(isFirstCharOne(status) ? 1 : 0));
                }
            } else {
                antenna.setStatus("0");
            }
            antenna.setDeviceId(antennaInfo.getDeviceId());
            antenna.setGantryId(antennaInfo.getGantryId());
            antenna.setUpdateTime(antennaInfo.getUpdateTime());
            antennaInfos.add(antenna);
        }
        return antennaInfos;
    }

}
